package com.cy.cur.aqs;

import org.openjdk.jol.info.ClassLayout;
import org.testng.annotations.Test;

public class SyncLearn {


    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(6000);
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        synchronized (o) {
            int a =1;
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }


    @Test
    public void t1() throws InterruptedException {
        // 等待偏向锁延迟期过去
        Thread.sleep(5000);
        Object obj = new Object();
        // 无锁状态
        System.out.println("无锁状态：");
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());

        // 第一个线程获取锁，进入偏向锁状态
        Thread t1 = new Thread(() -> {
            synchronized (obj) {
                System.out.println("偏向锁状态：");
                System.out.println(ClassLayout.parseInstance(obj).toPrintable());
            }
        });
        t1.start();
        t1.join();

        // 第二个线程竞争锁，可能升级为轻量级锁或重量级锁
        Thread t2 = new Thread(() -> {
            synchronized (obj) {
                System.out.println("加锁状态（可能是轻量级锁或重量级锁）：");
                System.out.println(ClassLayout.parseInstance(obj).toPrintable());
            }
        });
        t2.start();
        t2.join();
    }

    @Test
    public void t2() throws InterruptedException {
        // 等待偏向锁延迟期过去
        Thread.sleep(5000);
        // 创建一个对象
        Object lock = new Object();
        // 打印无锁状态下的对象头信息
        System.out.println("无锁状态:");
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());

        // 第一个线程获取锁，进入偏向锁状态
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("偏向锁状态:");
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
                try {
                    // 让线程持有锁一段时间，方便其他线程来竞争
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        // 短暂等待，确保 t1 已经获取到偏向锁
        Thread.sleep(1000);
        // 第二个线程竞争锁，可能导致锁升级
        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("加锁状态（可能是轻量级锁或重量级锁）:");
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
            }
        });
        t2.start();

        // 等待两个线程执行完毕
        t1.join();
        t2.join();

        // 为了更明显地观察到重量级锁的情况，我们可以增加多个线程竞争
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                synchronized (lock) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            threads[i].start();
        }

        // 等待所有线程执行完毕
        for (Thread thread : threads) {
            thread.join();
        }

        // 再次打印对象头信息，此时大概率是重量级锁状态
        System.out.println("最终锁状态（大概率是重量级锁）:");
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }
}
